pub mod client;
pub mod common;
pub mod param;
pub mod server;

use clap::Parser;
use client::Client;
use log::{info, LevelFilter};
use param::Param;
use std::io::Write;

fn log_init(level: u16) {
    let level_filter = match level {
        0 => LevelFilter::Off,
        1 => LevelFilter::Error,
        2 => LevelFilter::Warn,
        3 => LevelFilter::Info,
        4 => LevelFilter::Debug,
        5 => LevelFilter::Trace,
        _ => LevelFilter::Info,
    };
    env_logger::Builder::new()
        .filter(None, level_filter)
        .format(|buf, recode| {
            let ts = buf.timestamp_millis();
            let style = buf.default_level_style(recode.level());
            writeln!(
                buf,
                "[{ts} {style}{}{style:#} {}:{:?}] {}",
                recode.level(),
                recode.file().unwrap_or_default(),
                recode.line().unwrap_or_default(),
                recode.args()
            )
        })
        .init();
}

fn print_to_stdout(data: Vec<u8>) {
    let str = String::from_utf8(data).unwrap();
    println!("{str}");
}

fn main() {
    let _ = ylong_runtime::builder::RuntimeBuilder::new_multi_thread()
        .worker_stack_size(16 * 1024 * 1024)
        .worker_num(64)
        .keep_alive_time(std::time::Duration::from_secs(10))
        .build_global();

    let param = Param::parse();

    log_init(param.get_level());

    info!("{:#?}", param);

    match param.is_server() {
        true => {
            ylong_runtime::block_on(async { server::start_server(&param).await });
        }
        false => {
            ylong_runtime::block_on(async {
                if let Some(mut client) = Client::new(param, print_to_stdout).await {
                    if let Err(err) = client.execute_command().await {
                        log::error!("execute_command {err:?}");
                    };
                }
            });
        }
    }
}
